package com.fxu.framework.biz.util;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.fxu.framework.core.base.Constant;
import com.fxu.framework.core.base.Result;
import com.fxu.framework.core.enums.LanguageEnum;
import com.fxu.framework.core.holder.RequestHolder;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * 错误工具类
 * @author fangxu
 * @version 2025-06-05
 */
@Component
public final class ErrorUtil {
	private final static Map<String, Map<LanguageEnum, String>> LANG_MAP = new HashMap<>();
	private final static Map<String, Integer> CODE_MAP = new HashMap<>();

	/**
	 * 初始化 错误信息
	 * @param list 错误配置信息
	 * @return 初始化后的MAP
	 */
	public static Map<String, Map<LanguageEnum, String>> init(List<ErrorInfo> list) {
		for (ErrorInfo errorInfo : list) {
			Map<LanguageEnum, String> map = getMap(errorInfo);
			LANG_MAP.put(errorInfo.getZh(), map);
			LANG_MAP.put(errorInfo.getEn(), map);
			CODE_MAP.put(errorInfo.getZh(), errorInfo.getCode());
			CODE_MAP.put(errorInfo.getEn(), errorInfo.getCode());
		}
		return LANG_MAP;
	}

	// 获取语言MAP
	private static Map<LanguageEnum, String> getMap(ErrorInfo config) {
		Map<LanguageEnum, String> map = new HashMap<>();
		for (LanguageEnum languageEnum : LanguageEnum.values()) {
			Object value = ReflectUtil.getFieldValue(config, languageEnum.getField());
			map.put(languageEnum, value == null ? "" : String.valueOf(value));
		}
		return map;
	}

	/**
	 * 获取语言报头
	 * @return LanguageEnum
	 */
	public static LanguageEnum getLanguage() {
		HttpServletRequest request = RequestHolder.getRequestMayNull();
		if (request == null) return LanguageEnum.ZH_CN;
		String language = request.getHeader(Constant.HEADER_LANG);
		if (language == null) {
			language = request.getHeader(StrUtil.upperFirst(Constant.HEADER_LANG));
		}
		return LanguageEnum.find(language);
	}

	/**
	 * 获取对应语言的错误信息
	 * @return 错误信息
	 */
	public static String getLangMsg(LanguageEnum language, String msg) {
		if (LANG_MAP.containsKey(msg)) {
			Map<LanguageEnum, String> map = LANG_MAP.get(msg);
			if (map != null) {
				msg = map.getOrDefault(language, msg);
			}
		}
		return msg;
	}

	/**
	 * 获取对应语言的错误信息
	 * @return 错误信息
	 */
	public static String getErrorMsg(String msg, Object ...args) {
		LanguageEnum language = getLanguage();
		msg = getLangMsg(language, msg);
		if (msg.contains("%s") && args != null && args.length > 0) {
			Object[] newArgs = Arrays.stream(args).filter(Objects::nonNull)
					.map(v -> getLangMsg(language, v.toString())).toArray();
			msg = String.format(msg, newArgs);
		}
		return msg;
	}

	/**
	 * 获取对应语言的错误信息
	 * @return 错误代码
	 */
	public static int getErrorCode(String msg) {
		Integer code = CODE_MAP.getOrDefault(msg, 500);
		return code == null ? 500 : code;
	}

	/**
	 * 获取对应语言的错误信息
	 * @return 错误信息
	 */
	public static <T> Result<T> getError(String msg, Object ...args) {
		return Result.error(getErrorCode(msg), getErrorMsg(msg, args));
	}

	/**
	 * 获取对应语言的错误信息
	 * @return 错误信息
	 */
	public static ErrorVo getErrorVo(String msg, Object ...args) {
		return new ErrorVo(getErrorCode(msg), getErrorMsg(msg, args));
	}

	@Data
	@NoArgsConstructor
	@AllArgsConstructor
	public static class ErrorVo {
		@ApiModelProperty(value = "代码")
		private Integer code;

		@ApiModelProperty(value = "错误信息")
		private String msg;
	}

	@Data
	public static class ErrorInfo {
		@ApiModelProperty(value = "代码")
		private Integer code;

		@ApiModelProperty(value = "中文")
		private String zh;

		@ApiModelProperty(value = "英文")
		private String en;

		@ApiModelProperty(value = "法语")
		private String fra;

		@ApiModelProperty(value = "繁体中文")
		private String cht;

		@ApiModelProperty(value = "蒙古语")
		private String mn;
	}
}
